package cn.iocoder.yudao.module.system.controller.admin.useractivity;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.dal.dataobject.useractivity.UserActivityStatsDO;
import cn.iocoder.yudao.module.system.dal.dataobject.useractivity.UserDailyActivityDO;
import cn.iocoder.yudao.module.system.service.useractivity.UserActivityStatsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;

/**
 * 用户活动统计 Controller
 *
 * @author 系统开发团队
 */
@Tag(name = "管理后台 - 用户活动统计")
@RestController
@RequestMapping("/system/user-activity-stats")
@Validated
public class UserActivityStatsController {

    @Resource
    private UserActivityStatsService userActivityStatsService;

    // ========== 活动统计数据查询 ==========

    @GetMapping("/page")
    @Operation(summary = "获得用户活动统计分页")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<PageResult<UserActivityStatsDO>> getUserActivityStatsPage(
            @RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @RequestParam(value = "statType", required = false) Integer statType,
            @RequestParam(value = "calculationStatus", required = false) Integer calculationStatus,
            @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        PageResult<UserActivityStatsDO> pageResult = userActivityStatsService.getUserActivityStatsPage(
                startDate, endDate, statType, calculationStatus, pageNo, pageSize);
        return success(pageResult);
    }

    @GetMapping("/overview")
    @Operation(summary = "获得用户活动统计概览")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<Map<String, Object>> getUserActivityStatsOverview(
            @RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
        Map<String, Object> overview = userActivityStatsService.getUserActivityStatsOverview(startDate, endDate);
        return success(overview);
    }

    @GetMapping("/trend")
    @Operation(summary = "获得用户活动趋势")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<List<UserActivityStatsDO>> getUserActivityTrend(
            @RequestParam(value = "startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate startDate,
            @RequestParam(value = "endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate endDate,
            @RequestParam(value = "statType", defaultValue = "1") Integer statType) {
        List<UserActivityStatsDO> trend = userActivityStatsService.getUserActivityTrend(startDate, endDate, statType);
        return success(trend);
    }

    @GetMapping("/detail")
    @Operation(summary = "获得用户活动统计详情")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<UserActivityStatsDO> getUserActivityStatsDetail(
            @RequestParam("statDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate statDate,
            @RequestParam(value = "statType", defaultValue = "1") Integer statType) {
        UserActivityStatsDO detail = userActivityStatsService.getUserActivityStatsDetail(statDate, statType);
        return success(detail);
    }

    @GetMapping("/latest")
    @Operation(summary = "获得最新的用户活动统计")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<List<UserActivityStatsDO>> getLatestUserActivityStats(
            @RequestParam(value = "statType", defaultValue = "1") Integer statType,
            @RequestParam(value = "limit", defaultValue = "7") Integer limit) {
        List<UserActivityStatsDO> latest = userActivityStatsService.getLatestUserActivityStats(statType, limit);
        return success(latest);
    }

    // ========== 用户日活动管理 ==========

    @GetMapping("/daily-activity/page")
    @Operation(summary = "获得用户日活动分页")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<PageResult<UserDailyActivityDO>> getUserDailyActivityPage(
            @RequestParam(value = "userId", required = false) Long userId,
            @RequestParam(value = "userType", required = false) Integer userType,
            @RequestParam(value = "activityDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate activityDate,
            @RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
            @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
        PageResult<UserDailyActivityDO> pageResult = userActivityStatsService.getUserDailyActivityPage(
                startDate, endDate, userId, null, userType, pageNo, pageSize);
        return success(pageResult);
    }

    @GetMapping("/daily-activity/{id}")
    @Operation(summary = "获得用户日活动")
    @Parameter(name = "id", description = "编号", required = true)
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<UserDailyActivityDO> getUserDailyActivity(@PathVariable("id") Long id) {
        UserDailyActivityDO activity = userActivityStatsService.getUserDailyActivity(id);
        return success(activity);
    }

    @GetMapping("/daily-activity/active-users")
    @Operation(summary = "获得活跃用户列表")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<List<UserDailyActivityDO>> getActiveUsers(
            @RequestParam(value = "activityDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate activityDate,
            @RequestParam(value = "startDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
            @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
            @RequestParam(value = "userType", required = false) Integer userType,
            @RequestParam(value = "limit", defaultValue = "100") Integer limit) {
        List<UserDailyActivityDO> activeUsers = userActivityStatsService.getActiveUsers(
                activityDate, startDate, endDate, userType, limit);
        return success(activeUsers);
    }

    @GetMapping("/daily-activity/high-active-users")
    @Operation(summary = "获得高活跃用户列表")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<List<UserDailyActivityDO>> getHighActiveUsers(
            @RequestParam(value = "startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate startDate,
            @RequestParam(value = "endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate endDate,
            @RequestParam(value = "minLoginDays", defaultValue = "7") Integer minLoginDays) {
        List<UserDailyActivityDO> highActiveUsers = userActivityStatsService.getHighActiveUsers(
                startDate, endDate, minLoginDays);
        return success(highActiveUsers);
    }

    @GetMapping("/daily-activity/return-users")
    @Operation(summary = "获得回流用户列表")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<List<UserDailyActivityDO>> getReturnUsers(
            @RequestParam(value = "startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate startDate,
            @RequestParam(value = "endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate endDate,
            @RequestParam(value = "inactiveDays", defaultValue = "7") Integer inactiveDays) {
        List<UserDailyActivityDO> returnUsers = userActivityStatsService.getReturnUsers(
                startDate, endDate, inactiveDays);
        return success(returnUsers);
    }

    // ========== 活动数据分析 ==========

    @GetMapping("/analysis/activity-change")
    @Operation(summary = "分析活动变化")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<Map<String, Object>> analyzeActivityChange(
            @RequestParam(value = "startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate startDate,
            @RequestParam(value = "endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate endDate,
            @RequestParam(value = "compareStartDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate compareStartDate,
            @RequestParam(value = "compareEndDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate compareEndDate) {
        Map<String, Object> analysis = userActivityStatsService.analyzeActivityChange(
                startDate, endDate, compareStartDate, compareEndDate);
        return success(analysis);
    }

    @GetMapping("/analysis/user-retention")
    @Operation(summary = "分析用户留存")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<Map<String, Object>> analyzeUserRetention(
            @RequestParam(value = "startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate startDate,
            @RequestParam(value = "endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate endDate,
            @RequestParam(value = "retentionDays", defaultValue = "7") Integer retentionDays) {
        Map<String, Object> analysis = userActivityStatsService.analyzeUserRetention(
                startDate, endDate, retentionDays);
        return success(analysis);
    }

    @GetMapping("/analysis/behavior-pattern")
    @Operation(summary = "分析行为模式")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<Map<String, Object>> analyzeBehaviorPattern(
            @RequestParam(value = "startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate startDate,
            @RequestParam(value = "endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate endDate) {
        Map<String, Object> analysis = userActivityStatsService.analyzeUserBehaviorPattern(startDate, endDate);
        return success(analysis);
    }

    // ========== 统计计算管理 ==========

    @PostMapping("/calculate")
    @Operation(summary = "计算用户活动统计")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:create')")
    public CommonResult<Boolean> calculateUserActivityStats(
            @RequestParam("statDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate statDate) {
        boolean result = userActivityStatsService.calculateUserActivityStats(statDate);
        return success(result);
    }

    @PostMapping("/batch-calculate")
    @Operation(summary = "批量计算用户活动统计")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:create')")
    public CommonResult<Boolean> batchCalculateUserActivityStats(
            @RequestParam("startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate startDate,
            @RequestParam("endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate endDate) {
        boolean result = userActivityStatsService.batchCalculateUserActivityStats(startDate, endDate);
        return success(result);
    }

    @PostMapping("/recalculate")
    @Operation(summary = "重新计算用户活动统计")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:update')")
    public CommonResult<Boolean> recalculateUserActivityStats(
            @RequestParam("statDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate statDate) {
        boolean result = userActivityStatsService.recalculateUserActivityStats(statDate);
        return success(result);
    }

    @GetMapping("/calculation-progress")
    @Operation(summary = "获得计算进度")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<Map<String, Object>> getCalculationProgress(
            @RequestParam(value = "startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate startDate,
            @RequestParam(value = "endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate endDate) {
        Map<String, Object> progress = userActivityStatsService.getCalculationProgress(startDate, endDate);
        return success(progress);
    }

    @GetMapping("/data-integrity")
    @Operation(summary = "检查数据完整性")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:query')")
    public CommonResult<Map<String, Object>> checkDataIntegrity(
            @RequestParam(value = "startDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate startDate,
            @RequestParam(value = "endDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate endDate) {
        Map<String, Object> integrity = userActivityStatsService.checkDataIntegrity(startDate, endDate);
        return success(integrity);
    }

    // ========== 数据管理 ==========

    @DeleteMapping("/expired-stats")
    @Operation(summary = "删除过期的活动统计数据")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:delete')")
    public CommonResult<Integer> deleteExpiredStats(
            @RequestParam("beforeDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate beforeDate) {
        int count = userActivityStatsService.deleteExpiredStats(beforeDate);
        return success(count);
    }

    @DeleteMapping("/expired-daily-activity")
    @Operation(summary = "删除过期的日活动数据")
    @PreAuthorize("@ss.hasPermission('system:user-activity-stats:delete')")
    public CommonResult<Integer> deleteExpiredDailyActivity(
            @RequestParam("beforeDate") @DateTimeFormat(pattern = "yyyy-MM-dd") @NotNull LocalDate beforeDate) {
        int count = userActivityStatsService.deleteExpiredDailyActivity(beforeDate);
        return success(count);
    }
}